package 文本搜索替换;

import javax.swing.*;
import javax.swing.text.DefaultHighlighter;
import javax.swing.text.Highlighter;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.*;

public class 文本替换例子 extends JFrame {
    private JTextArea textArea;
    private JTextField filePathField, searchField, replaceField;
    private Highlighter.HighlightPainter highlightPainter;
    private List<Integer> matchPositions = new ArrayList<>();
    private int currentMatchIndex = -1;

    public 文本替换例子() {
        setTitle("文本处理工具 v1.0");
        setSize(800, 600);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        initUI();
        highlightPainter = new DefaultHighlighter.DefaultHighlightPainter(Color.YELLOW);
    }

    private void initUI() {
        // 文件选择组件
        JPanel filePanel = new JPanel(new BorderLayout());
        filePathField = new JTextField();
        JButton openBtn = new JButton("打开文件");
        openBtn.addActionListener(this::openFile);
        filePanel.add(filePathField, BorderLayout.CENTER);
        filePanel.add(openBtn, BorderLayout.EAST);

        // 文本显示区域
        textArea = new JTextArea();
        JScrollPane scrollPane = new JScrollPane(textArea);

        // 搜索替换面板
        JPanel searchPanel = new JPanel(new GridLayout(2, 1));

        // 搜索组件
        JPanel searchRow = new JPanel(new BorderLayout());
        searchField = new JTextField();
        JButton searchBtn = new JButton("搜索");
        searchBtn.addActionListener(this::highlightMatches);
        searchRow.add(searchField, BorderLayout.CENTER);
        searchRow.add(searchBtn, BorderLayout.EAST);

        // 替换组件
        JPanel replaceRow = new JPanel(new BorderLayout());
        replaceField = new JTextField();
        JButton replaceBtn = new JButton("替换");
        replaceBtn.addActionListener(this::replaceText);
        replaceRow.add(replaceField, BorderLayout.CENTER);
        replaceRow.add(replaceBtn, BorderLayout.EAST);

        // 导航按钮
        JButton prevBtn = new JButton("上一个");
        prevBtn.addActionListener(e -> navigateMatches(-1));
        JButton nextBtn = new JButton("下一个");
        nextBtn.addActionListener(e -> navigateMatches(1));
        JPanel navPanel = new JPanel();
        navPanel.add(prevBtn);
        navPanel.add(nextBtn);

        searchPanel.add(searchRow);
        searchPanel.add(replaceRow);

        // 主布局
        getContentPane().setLayout(new BorderLayout());
        getContentPane().add(filePanel, BorderLayout.NORTH);
        getContentPane().add(scrollPane, BorderLayout.CENTER);

        JPanel southPanel = new JPanel(new BorderLayout());
        southPanel.add(searchPanel, BorderLayout.CENTER);
        southPanel.add(navPanel, BorderLayout.SOUTH);
        getContentPane().add(southPanel, BorderLayout.SOUTH);
    }

    private void openFile(ActionEvent e) {
        JFileChooser fc = new JFileChooser();
        if (fc.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
            File file = fc.getSelectedFile();
            filePathField.setText(file.getAbsolutePath());
            try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
                StringBuilder content = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null) {
                    content.append(line).append("\n");
                }
                textArea.setText(content.toString());
            } catch (IOException ex) {
                JOptionPane.showMessageDialog(this, "文件读取失败");
            }
        }
    }

    private void highlightMatches(ActionEvent e) {
        textArea.getHighlighter().removeAllHighlights();
        matchPositions.clear();
        currentMatchIndex = -1;

        String pattern = searchField.getText();
        if (pattern.isEmpty()) return;

        String text = textArea.getText();
        try {
            Pattern p = Pattern.compile(pattern);
            Matcher m = p.matcher(text);
            while (m.find()) {
                int start = m.start();
                int end = m.end();
                textArea.getHighlighter().addHighlight(start, end, highlightPainter);
                matchPositions.add(start);
            }
            if (!matchPositions.isEmpty()) {
                currentMatchIndex = 0;
                scrollToMatch(currentMatchIndex);
            }
        } catch (PatternSyntaxException ex) {
            JOptionPane.showMessageDialog(this, "无效的正则表达式");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    private void replaceText(ActionEvent e) {
        String search = searchField.getText();
        String replace = replaceField.getText();
        if (search.isEmpty()) return;

        try {
            String text = textArea.getText();
            Pattern p = Pattern.compile(search);
            Matcher m = p.matcher(text);
            String newText = m.replaceAll(replace);
            textArea.setText(newText);
        } catch (PatternSyntaxException ex) {
            JOptionPane.showMessageDialog(this, "无效的正则表达式");
        }
    }

    private void navigateMatches(int direction) {
        if (matchPositions.isEmpty()) return;

        currentMatchIndex += direction;
        if (currentMatchIndex < 0) currentMatchIndex = matchPositions.size() - 1;
        if (currentMatchIndex >= matchPositions.size()) currentMatchIndex = 0;

        scrollToMatch(currentMatchIndex);
    }

    private void scrollToMatch(int index) {
        int pos = matchPositions.get(index);
        try {
            Rectangle viewRect =textArea.modelToView(pos);
            textArea.scrollRectToVisible(viewRect);
            textArea.setCaretPosition(pos);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            new 文本替换例子().setVisible(true);
        });
    }
}

